package main

import (
	"fmt"
	"math/rand"
	"sync"
	"time"
)

var wg sync.WaitGroup

func init() {
	fmt.Println("\ntest init,init is called before main !\n")
}

func main() {

	rand.Seed(time.Hour.Microseconds())
	/*这个是块注释 跟c++ 一样*/
	//单行注释
	fmt.Println("my first go test\n")
	var stockcode int = 123
	var enddate = "2022-12-30"
	var urs_l = "Code=%d&endDate = %s"
	var target_url = fmt.Sprintf(urs_l, stockcode, enddate)
	fmt.Println(target_url)
	var i (int)
	var f float64
	var b bool
	var s string
	i, f = 1, 3
	fmt.Printf("%v %v %v %q\n", i, f, b, s)
	testconst()
	var max, str = getMaxNum(stockcode, i)
	fmt.Println("maxnumber = ", max, str, "test11")

	//testStruct()
	//testGoRoutine()
	//testChan()
	testLikePV()
	fmt.Println("程序结尾日志") //main 函数是一个goroutine 会先执行完这一条语句
	test02()
	test03()
	wg.Wait() //然后在这里进行阻塞，等待wg.Add(2) 生成的两个goroutine （p v）结束,然后才结束主线程

}
func testconst() {
	const (
		a  = iota //0
		b         //1
		c         //2
		d  = "ha" //独立值，iota += 1
		e         //"ha"   iota += 1
		f  = 100  //iota +=1
		g         //100  iota +=1
		gg        //值会跟上面相同 ，iotag+=1
		h  = iota //7,恢复计数
		i         //8
	)
	fmt.Println(a, b, c, d, e, f, g, gg, h, i)
}
func getMaxNum(a, b int) (int, string) {
	ret := 0
	if a > b {
		ret = a
	} else {
		ret = b
	}
	return ret, "test"
}

func testStruct() {
	type Books struct {
		title   string
		author  string
		subject string
	}

	var xiaoshuo Books
	xiaoshuo.author = "无极"
	xiaoshuo.title = "幻世"
	xiaoshuo.subject = "玄幻"
	fmt.Println(xiaoshuo)
}
func say(str string) {
	for i := 0; i < 5; i++ {
		time.Sleep(100 * time.Millisecond)
		fmt.Print(str, "\n")
	}

}
func testGoRoutine() {
	go say("world")
	say("hello")
}
func testChan() {
	ch := make(chan int, 10)

	for i := 0; i < 5; i++ {
		ch <- i
	}
	close(ch)
	//ch <- 123  //由此可知，当向关闭的 chan 打数据时，程序会崩溃！
	for v := range ch {
		fmt.Println(v)
	}
	fmt.Print("after for \n")
	for v := range ch {
		fmt.Println(v)
	}

	fmt.Println("由上可知chan 被读完之后，里面的元素就被清除了\n")
}

const pcount = 4
const vcount = 3

func likeP(ch chan int) {
	fmt.Println("likeP")
	//count := pcount
	//for ; count >= 0; count-- {
	for true {
		ret, ok := <-ch
		if ok {
			fmt.Println("p = ", ret, ok)
		} else {
			fmt.Println("chan has been closed ret=", ret, " ok=", ok)
			break
		}

	}

	defer wg.Done()
}
func likev(ch chan int) {
	fmt.Println("likev")
	count := vcount
	for true {
		num := rand.Intn(100)

		fmt.Println("v = ", num)
		ch <- num
		//time.Sleep(1000 * time.Millisecond)
		count -= 1
		if count <= 0 {
			close(ch)
			break

		}

	}
	defer wg.Done()
}

func testLikePV() {
	fmt.Println("testLikePV ")
	ch := make(chan int, 100)
	//go likev(ch)
	wg.Add(2)
	go likeP(ch)
	go likev(ch)
	fmt.Println("at the end of testLikePV 完全异步，所以这里日志先打印出来")
}
